//
//  SWSerialPortController.m
//  SerialPort
//
//  Created by MT-SW-003 on 2021/4/9.
//  Copyright © 2021 MT-SW-003. All rights reserved.
//

#import "SWSerialPortController.h"

@implementation SWSerialPortController



/*
* Loading config File and check config file
*
* @return check Instance of SWCheckData.
*/
- (id)loadingConfigFile{
    NSLog(@"loading Config File");
   
    id serialParamData = [SWLoadConfig loadJsonFile:@"serialConfig.json"];
    id configData = [SWLoadConfig loadJsonFile:@"config.json"];

    //check serialport param
    check = [[SWCheckData alloc]initWithSerialData:serialParamData withConfigData:configData];
    BOOL isChecked = [check checkConfigData];
    NSLog(@"configFile isChecked:%@",isChecked?@"YES":@"NO");
    if (isChecked == 1) {
        NSLog(@"check config success");
    }
    else {
        NSLog(@"check config faild");
    }
    return check;
}



/*
* Open the serialPort device.
*
* @param devPath The path of serial device.
*
* @return fd Number of open device.
*/
- (int)openSerialPort:(NSString *)devpath {
    serialPort = [[SWSeilal alloc]init];
    
    //open device
    NSLog(@"open device:%@",devpath);
    fd = [serialPort serialDevice:[SWSelectDevice checkAndOpenDeviceByDevicePath:devpath]];
    
    //open device failed stop running
    if (fd <0) {
        fd = -1;
        NSLog(@"open device failed");
    }
    return fd;
}



/*
* Set the serialPort device.
*/
- (void)setSerialPortForDevice:(int)fd
                  withBaudRate:(int)baudRate
                   withDataBit:(int)dataBit
                   withStopBit:(int)stopBit
                    withParity:(char)parity {
    
    //set serialPort param
    NSLog(@"set serialPort param");
    int isSetOK = [serialPort serialConfigForDevice:fd
                                       withBaudRate:baudRate
                                        withDataBit:(int)dataBit
                                        withStopBit:(int)stopBit
                                         withParity:(char)parity];
        
    // whether serialPort param was set successfully
    //set successs
    if (isSetOK == 1) {
        NSLog(@"serialPort param isValid:%@",isSetOK?@"YES":@"NO");
        NSLog(@"set serialPort param success");
    //set failed
    }else {
            NSLog(@"serialPort param isValid:%@",isSetOK?@"YES":@"NO");
            NSLog(@"set serialPort param failed");
        }
}



/*
* Write data to the serialPort device with ascii string.
*
* @param fd The number of opened serial device.
*
* @param writeStr  Written string.
*/
- (ssize_t)writeData:(int)fd  withASCIIStr:(NSString *)writeStr {
    char *writeData = (char *)[writeStr UTF8String];
//    NSLog(@"%s",writeData);
//    strcat(writeData,"\r\n\0");
    size_t len = strlen(writeData);
    ssize_t writeLength = [serialPort writeDataToDevice:fd
                                      writeBuff:writeData
                                writeDataLength:len];
    return  writeLength;
}



/*
* Write data to the serialPort device with hex string.
*
* @param fd The number of opened serial device.
*
* @param writeStr  Written string.
*/
- (ssize_t)writeData:(int)fd  withHEXStr:(NSString *)writeStr {
   
    char *writeData = (char *)[writeStr UTF8String];
    char *hexStr=[self chsToHex:writeData];
//    strcat(hexStr,"\r\n\0");
    size_t len = strlen(hexStr);
    NSLog(@"==hex to str :%s----len:%zu",hexStr,len);
    ssize_t writeLength = [serialPort writeDataToDevice:fd
                                      writeBuff:hexStr
                                writeDataLength:len];
    return  writeLength;
}




/*
* Read data from serial device
*
* @param readData Read data of serial device.
*
* @return readStr The String of read data.
*/
- (NSDictionary*)readData:(int)fd {
    NSMutableDictionary *readDataDict = [serialPort readDataFromDevice:fd];
//    NSLog(@"read data dict:%@",readDataDict);
    return readDataDict;
}



/*
* Close serial device.
*
* @param fd NUmber of opened serial device.
*
*/
- (void)closeSerialPort:(int)fd {
    //close device
    [serialPort serialCloseDevice:fd];
    NSLog(@"stop serial port");
}



/*
* get device path array
*
* @return devList Serial device path array.
*/
- (NSArray*)deviceArray {
    NSArray *devList = [SWSelectDevice scanDevice];
//    NSLog(@"device:%@",devList);
    return devList;
}



/*
* ASCII string conversion to HEX string.
*
* @return HEX string.
*/
- (char *)chsToHex:(char*)chs {
    char hex[16] = { '0', '1', '2', '3', '4', '5', '6', \
        '7', '8','9', 'A', 'B', 'C', 'D', 'E', 'F'
    };

    int len = (int)strlen ( chs );
    char* hexStr = NULL ;
    hexStr = (char*)calloc ( len * 3 + 1, sizeof(char) );
    
    int i = 0;
    while( i < len )
    {
        hexStr[i*2] = hex[(int)( (char)chs[i] / 16 )] ;
        hexStr[i*2 + 1] = hex[(int)( (char)chs[i] % 16 )] ;
        ++i;
    }
    return hexStr;
}


/*
* HEX string conversion to ASCII string.
*
* @return ASCII string.
*/
- (char *)hexToChs:( char* )ascii {
    int len =(int)strlen ( ascii ) ;
    if( len%2 != 0 ){
        return NULL ;
    }
    char *chs = NULL ;
    chs = (char*)calloc( len / 2 + 1, sizeof(char) );

    int  i = 0 ;
    char ch[2] = {0};
    while( i < len ) {
        ch[0] = ( (int)ascii[i] > 64 ) ? ( ascii[i]%16 + 9 ) : ascii[i]%16 ;
        ch[1] = ( (int)ascii[i + 1] > 64 ) ? ( ascii[i + 1]%16 + 9 ) : ascii[i + 1]%16 ;
        
        chs[i/2] = (char)( ch[0]*16 + ch[1] );
        i += 2;
    }
    return chs ;
}

@end
